import * as path from 'node:path';

import { Inject, Injectable, Logger } from '@nestjs/common';
import * as fse from 'fs-extra';

import { type IScheDuleRule } from '../../interface.d';
import { fullScreenChrome } from '../../utils';
import { DataFactory } from '../common/global/dataFactory/dataFactory.service';

type IRuntimeMaterial = IScheDuleRule & {
  sampleCoursePath: string;
};

@Injectable()
export class XhsService {
  @Inject()
  private globalService: DataFactory;

  private readonly logger = new Logger(XhsService.name);

  async run(rule: IRuntimeMaterial) {
    const { cacheDirName, jsonConfigPath } = rule;

    const browser = await this.globalService.createBroswer(cacheDirName);

    const [page] = await browser.pages();

    await page.setRequestInterception(true);

    page.on('request', interceptedRequest => {
      if (interceptedRequest.isInterceptResolutionHandled()) return;

      const url = interceptedRequest.url();

      const reg = /(\.mp4|\.png|\.jpg|\.jpeg)/gi;

      if (url.match(reg)) {
        interceptedRequest.abort();
      } else {
        interceptedRequest.continue();
      }
    });

    await page.goto('https://creator.xiaohongshu.com/login', { waitUntil: 'networkidle0' });

    page.off('request');

    await page.setRequestInterception(false);

    if (page.url().includes('login')) {
      this.logger.error('未登录');
      await browser.close();
      return;
    }

    await page.bringToFront();

    fullScreenChrome();

    this.logger.verbose('1、点击发布笔记');

    await page
      .locator('.publish-video')
      .setTimeout(20 * 1000)
      .click({ delay: 5000 });

    this.logger.verbose('2、点击上传图文');

    await page
      .locator('.creator-tab .title ::-p-text(上传图文)')
      .setTimeout(20 * 1000)
      .click({ delay: 5000 });

    type IJson = {
      douyinPngList: string[];
      name: string;
      tags: string[];
    };

    const { douyinPngList: xhsPngList, name, tags } = <IJson>fse.readJSONSync(jsonConfigPath);

    const desktopPath = this.globalService.getDesktopPath();

    const images = xhsPngList.map(i => path.join(desktopPath, i.replace(/[\\\\/]/gi, path.sep)));

    this.logger.verbose('上传头图');
    const [firstImage, ...otherImages] = images;

    const uploadBtn = await page.waitForSelector('input.upload-input[type=file]');

    await uploadBtn?.uploadFile(firstImage);

    this.logger.verbose('等待头图上传完毕');
    await page.waitForSelector('.format-img .mask .uploading', { hidden: true });

    this.logger.verbose('上传剩余图片');

    const uploadInputFile = await page.waitForSelector('input[type=file]');

    await uploadInputFile?.uploadFile(...otherImages);

    this.logger.verbose('等待全部上传完毕');
    await page.waitForResponse(
      res => res.url().includes('/faas/proto/json-to-proto-json-to-proto/proxy') && res.status() === 200,
    );

    this.logger.verbose('输入标题');
    await page.locator('.el-input__inner').fill(name);

    this.logger.verbose('输入标签');
    const editorElement = await page.$('#post-textarea');
    await editorElement?.focus();

    await editorElement.scrollIntoView();

    for (const tagValue of tags) {
      await editorElement?.type(`#${tagValue}`, { delay: 100 });

      await page.waitForResponse(res => res.url().includes('web_api/sns/v1/search/topic') && res.status() === 200);

      await page.keyboard.press('Enter', { delay: 5000 });

      await page.keyboard.press('Enter', { delay: 2000 });
    }

    this.logger.verbose('点击发布按钮');
    await page.locator('.publishBtn::-p-text(发布)').click({ delay: 2000 });

    await page.locator('::-p-text(发布成功)').wait();
    this.logger.verbose('发布成功了');

    await browser.close();
  }
}
